package com.xinzhidi.web.netty.utils;

import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.collections.CollectionUtils;

import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @Description tcp数据处理工具类
 * @Author chenJF & LT
 * @Date 2021-10-18 19:19
 */
public class FormatData {
    private static ConcurrentMap tcpMap = new ConcurrentHashMap<Integer, List>();

    private static ByteBuf byteBuf = Unpooled.buffer(8);


    /**
     * 十六进制字符串转化为十进制的数据
     *
     * @param couts
     * @return
     */
    public static Long TotenLong(String couts) {
        if (couts.length() == 2) {
            Long lowByte = Long.parseLong(couts.substring(0, 2), 16);

            return lowByte;
        }
        if (couts.length() == 4) {
            Long lowByte = Long.parseLong(couts.substring(0, 2), 16);

            Long higByte = Long.parseLong(couts.substring(2, 4), 16);

            Long TenCout = lowByte + higByte * 256;
            return TenCout;
        }
        if (couts.length() == 8) {
            Long o_t = Long.parseLong(couts.substring(0, 2), 16);
            Long f_f = Long.parseLong(couts.substring(2, 4), 16);
            Long f_s = Long.parseLong(couts.substring(4, 6), 16);
            Long s_s = Long.parseLong(couts.substring(6, 8), 16);
            Long TenCout = o_t + f_f * 256 + f_s * 256 * 256 + s_s * 256 * 256 * 256;
            return TenCout;
        }
        return null;
    }

    /**
     * 十六进制字符串转化为十进制的数据
     *
     * @param couts
     * @return
     */
    public static Integer Toten(String couts) {
        if (couts.length() == 2) {
            Integer lowByte = Integer.parseInt(couts.substring(0, 2), 16);

            return lowByte;
        }
        if (couts.length() == 4) {
            Integer lowByte = Integer.parseInt(couts.substring(2, 4), 16);

            Integer higByte = Integer.parseInt(couts.substring(0, 2), 16);

            Integer TenCout = lowByte + higByte * 256;
            return TenCout;
        }
        if (couts.length() == 8) {
            Integer o_t = Integer.parseInt(couts.substring(6, 8), 16);
            Integer f_f = Integer.parseInt(couts.substring(4, 6), 16);
            Integer f_s = Integer.parseInt(couts.substring(2, 4), 16);
            Integer s_s = Integer.parseInt(couts.substring(0, 2), 16);
            Integer TenCout = o_t + f_f * 256 + f_s * 256 * 256 + s_s * 256 * 256 * 256;
            return TenCout;
        }
        return null;
    }

    /**
     * 16进制字符串转化为ASCII
     *
     * @param HexString
     * @return
     */
    public static String hexToASCII(String HexString) {
        StringBuilder sb = new StringBuilder();
        StringBuilder temp = new StringBuilder();
        for (int i = 0; i < HexString.length() - 1; i += 2) {
            //grab the hex in pairs
            String output = HexString.substring(i, (i + 2));
            //convert hex to decimal
            int decimal = Integer.parseInt(output, 16);
            //convert the decimal to character
            //跟甲方沟通，sn和pn中有00代表结束后面的字符串就不需要处理
            if (0 == decimal) {
                break;
            }
            sb.append((char) decimal);
            temp.append(decimal);
        }
        return sb.toString();
    }

    /**
     * 字符串转化为 参数编码与对应的参数值
     *
     * @param ParmData
     * @return
     */
    public static HashMap ParmInfoTrans(String ParmData) {
        HashMap<String, Object> ReParmdata = new HashMap<>();
        if (ParmData != null && ParmData.length() > 0) {
            for (int i = 0; i < ParmData.length() - 1; i += 16) {
                String OneParm = ParmData.substring(i, i + 16);
                String Parmname = Toten(OneParm.substring(0, 8)).toString();
                Long OneParmValue = TotenLong(OneParm.substring(8, 16));
                ReParmdata.put(Parmname, OneParmValue);
            }
            return ReParmdata;
        }
        return null;
    }

    /**
     * 多个包拼接
     *
     * @param data
     * @return
     */
    public static String DataMontage(List<String> data, Integer allAddrHash) {

        List<Integer> sortNum = new ArrayList<>();
        Map<Integer, Integer> match = new HashMap<>();
        List<Integer> allNum = new ArrayList<>();
        Integer lAllDataSize = null;
        Integer AllDataSize = 0;
        Integer unPacketNum = null;
        Integer Num = 0;
        for (String string : data) {
            lAllDataSize = Toten(string.substring(24, 32));
            unPacketNum = Toten(string.substring(40, 44));
            Integer unPacketIndex = Toten(string.substring(44, 48));
            //System.out.print(Toten(string.substring(52, 56)));
            AllDataSize += Toten(string.substring(52, 56));
            sortNum.add(unPacketIndex);
            match.put(unPacketIndex, Num);
            Num++;
        }
        Collections.sort(sortNum);
        Integer PacketNum = (sortNum.get(0) + sortNum.get(sortNum.size() - 1) + 1);
        String msg = null;
        if (PacketNum.equals(unPacketNum) && AllDataSize.equals(lAllDataSize)) {
            Integer i = 0;
            while (i < data.size()) {
                if (i.equals(0)) {
                    msg = data.get(match.get(sortNum.get(i)));
                    String msgFrame = msg.substring(0, 24);
                    msg = msgFrame.concat(msg.substring(56, msg.length()));
                } else {
                    String msg1 = data.get(match.get(sortNum.get(i)));
                    msg = msg.concat(msg1.substring(56, msg1.length()));
                }
                i++;
            }
            tcpMap.remove(allAddrHash);
            return msg;
        } else {
            System.out.print("数据接收错误");
            return null;
        }
    }


    /**
     * 转化字符串为十六进制编码
     */

    public static String toHexString(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }


    /**
     * @param byteBuffer
     */
    public static String TcpBufferToString(ByteBuffer byteBuffer, Integer allAddrHash) {
        StringBuffer stringBuffer = new StringBuffer();

        for (int i = 0; i < byteBuffer.array().length; i++) {
            String hexString = Integer.toHexString(byteBuffer.array()[i] & 0xFF);
            if (hexString.length() == 1) {
                hexString = "0" + hexString;
            }
            stringBuffer.append(hexString);
        }

        String msg = stringBuffer.toString();
        //System.out.print(msg);
        char flag = msg.charAt(9);
        if (flag == '0' || msg.length() == 24) {
            //Integer unFrameLen = Toten(msg.substring(4, 8));
            //return msg.substring(0, 8+unFrameLen*2);
            return msg;
        } else {
            Integer lAllDataSize = Toten(msg.substring(24, 32));
            Integer unAllDataCRC = Toten(msg.substring(32, 36));
            Integer unPacketSize = Toten(msg.substring(36, 40));
            Integer unPacketNum = Toten(msg.substring(40, 44));
            Integer unPacketIndex = Toten(msg.substring(44, 48));
            Integer unDataCRC = Toten(msg.substring(48, 52));
            Integer unDataBuffSize = Toten(msg.substring(52, 56));

            if (unPacketIndex < unPacketNum - 1) {
                if (!(tcpMap.containsKey(allAddrHash))) {
                    List<String> list = new ArrayList<>();
                    list.add(msg);
                    tcpMap.put(allAddrHash, list);
                } else {
                    List list = (List) tcpMap.get(allAddrHash);
                    list.add(msg);
                    tcpMap.put(allAddrHash, list);
                }
                return null;
            } else if (unPacketIndex == 0 && unPacketNum == 1) {
                return msg.substring(0, 24).concat(msg.substring(56, msg.length()));
            } else {
                List list = (List) tcpMap.get(allAddrHash);
                list.add(msg);
                tcpMap.put(allAddrHash, list);
                List<String> list1 = (List<String>) tcpMap.get(allAddrHash);
                return DataMontage(list1, allAddrHash);
            }
        }
    }

    /**
     * 整数的点表版本转成字符串
     *
     * @param data
     * @return
     */
    public static String unProduceChange(Integer data) {
        Integer ProduceLow = data & 0x000003ff;
        String Low = String.format("%04d", ProduceLow);
        String ProduceLowS = Low.substring(Low.length() - 3, Low.length());
        Integer ProduceMid = (data & 0x000ffc00) / 1024;
        String Mid = String.format("%04d", ProduceMid);
        String ProduceMidS = Mid.substring(Mid.length() - 3, Mid.length());
        Integer ProduceHig = (data & 0xfff00000) / 1048576;
        String Hig = String.format("%04d", ProduceHig);
        String ProduceHigS = Hig.substring(Hig.length() - 3, Hig.length());
        String ProduceS = ProduceHigS + '.' + ProduceMidS + '.' + ProduceLowS;
        return ProduceS;
    }

    //============================================高低位转换===================================

    public static String decToHex(int dec) {
        if (dec > 0) {
            String hex = "";
            while (dec != 0) {
                String h = Integer.toString(dec & 0xff, 16);
                if ((h.length() & 0x01) == 1) {
                    h = '0' + h;
                }
                hex = hex + h;
                dec = dec >> 8;
            }
            return hex;
        }
        if (dec < 0) {
            String hex = "";
            while (dec != -1) {
                String h = Integer.toString(dec & 0xff, 16);
                if ((h.length() & 0x01) == 1) {
                    h = '0' + h;
                }
                hex = hex + h;
                dec = dec >> 8;
            }
            return hex;
        }
        return null;
    }

    public static String decToHex(Long dec) {
        String hex = "";
        hex = Long.toHexString(dec);
        if (hex.length() == 1) {
            hex = "0" + hex;
        }
        return hex;
    }

    public static Double hexToDouble(String hex) {
        if (hex.length() != 16) {
            return null;
        }
        byte[] dbBytes2 = new byte[8];
        for (int i = 0; i < 8; i++) {
            int in = Integer.parseInt(hex.substring(2 * i, (i + 1) * 2), 16);
            byte in1 = (byte) in;
            dbBytes2[i] = in1;
        }
        byteBuf.writeBytes(dbBytes2);
        return byteBuf.readDouble();
    }

    /**
     * 根据经度获取时区；例如121：+8;-121：-8;返回值为字符串（返回正数时候带+符号）
     *
     * @param currentLon
     * @return
     */
    public static String caculateTimeZone(double currentLon) {
        int timeZone;
        int shangValue = (int) (currentLon / 15);
        double yushuValue = Math.abs(currentLon % 15);
        if (yushuValue <= 7.5) {
            timeZone = shangValue;
        } else {
            timeZone = shangValue + (currentLon > 0 ? 1 : -1);
        }
        return timeZone >= 0 ? "+" + Math.abs(timeZone) : "-" + Math.abs(timeZone);
    }

    /**
     * 十进制转十六进制
     *
     * @param number 十进制数
     * @return formatterLength  格式化长度
     */
    public static String tenToHexadecimal(Integer number, Integer formatterLength) {
        String message = String.format("%0" + formatterLength * 2 + "x", number);
//        System.out.println(message);
        return message;
    }

    /**
     * 将16进制字符串转换为byte数组
     *
     * @param hexItr 16进制字符串
     * @return
     */
    public static byte[] hexItr2Arr(String hexItr) {
        try {
            char[] data = hexItr.toCharArray();
            return Hex.decodeHex(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] hex2bytes(String hex) {
        int len = hex.length();
        byte[] result = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            result[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        return result;
    }

    public static String byteToHex(byte num) {
        char[] hexDigits = new char[2];
        hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
        hexDigits[1] = Character.forDigit((num & 0xF), 16);
        return new String(hexDigits);
    }

    public static String encodeHexString(byte[] byteArray) {
        StringBuffer hexStringBuffer = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            hexStringBuffer.append(byteToHex(byteArray[i]));
        }
        return hexStringBuffer.toString();
    }

    // 16进制转换10进制
    public static int hex2decimal(String hex) {
        return Integer.parseInt(hex, 16);
    }

    public static void main(String args[]) {

        System.out.println("FEFEFE6846547113430000000406AC0401010061E616".length());
        System.out.println("FEFEFE6846547113430000000406AC04010061E516".length());
        System.out.println("FEFEFE6846685401430000000406AC0401015000BA16".length());

//        System.out.println("FEFE684611570643000000812990200100250025002537273827381201003812010007000000000000000550004958140101172041000716".replaceAll("FE" , "").substring(44 , 46));

//        System.out.println(ceshi());

//        System.out.println(tenToHexadecimal(610 , 2));

//        String ss = "0122334455";
//        System.out.println(ss.substring(0, 2));
//        System.out.println(ss.substring(2, ss.length()));

//        System.out.println(Toten("0262"));


//        System.out.println("FEFEFE6846A0A1A2A3A4A5A6040301006e9916".length());

//        Map<String,Object> m = new HashMap<>();
//        m.put("aa" , 33.6);
//        System.out.println(new BigDecimal(m.get("aa").toString()));

//        System.out.println(Toten("636565626963"));

//        String ss = "FEFEFE68466854014300000081299020010025002500259999999902830200956002004110000087000000057000512817010117207100C116";
//        ss.replaceAll(" ", "");
//        String mm = ss.substring(44 * 2, 46 * 2);
//        System.out.println(mm);
//
//        System.out.println("FEFEFE68466854014300000001039020016316".length());
//        System.out.println("FEFEFE68468361064300000001039020019016".length());

//        System.out.println(HexadecimalUtil.hexConvertToHighLow(tenToHexadecimal(50, 2)));

//        List<Integer> list = Lists.newArrayList();
//        System.out.println(list.size());

//        BigDecimal decimal = new BigDecimal("12345.6789");
//        BigInteger unscaledValue = decimal.unscaledValue();
//        String hex = unscaledValue.toString(16);
//
//        System.out.println("Hexadecimal representation: " + hex);
//
//        System.out.println(FormatData.tenToHexadecimal(21, 1));

//        System.out.println("100转为十六进制为：" + FormatData.\(100, 2));
//        System.out.println("0064转为十进制为：" + Toten("01FB"));

//        System.out.println(HexadecimalUtil.hexConvertToHighLow(FormatData.tenToHexadecimal(100, 2)));

//        String ss = tenToHexadecimal(600 , 2);
//        System.out.println(HexadecimalUtil.convertToHighLow(ss));
//        System.out.println(tenToHexadecimal(1 , 1));
//        System.out.println(hex2decimal("FF"));

//        String he = tenToHexadecimal(121215, 3);
//        System.out.println("十进制转十六进制为：" + he);
//        Integer str = hex2decimal(he);
//        System.out.println("十六进制转十进制为：" + str);

//        System.out.println(hex2decimal("01"));

//        System.out.println(Integer.valueOf("0031"));

//            value += FormatData.hex2decimal(ss.substring(i * 2, i * 2 + 2));
//            System.out.println("得到的值为：" + value);

//        for (int i = 0; i < 100; i++) {
//            System.out.println(IdUtils.generateUniqueNumber(8));
//
//        }

//        System.out.println(IdUtils.generateUniqueNumber());

//        System.out.println("1f903b0000060009007603ee00ee0002000500d800000000000100600920032c01c201c80050001e00".length()/2);

//        System.out.println(tenToHexadecimal(23, 1));
//        System.out.println(tenToHexadecimal(06, 1));
//        System.out.println(tenToHexadecimal(12, 1));
//        System.out.println(tenToHexadecimal(17, 1));
//        System.out.println(tenToHexadecimal(21, 1));
//        System.out.println(tenToHexadecimal(50, 1));
//        System.out.println(hex2decimal("29"));
//        System.out.println(hex2decimal("40"));
//        System.out.println(hex2decimal("16"));


//        String str=String.valueOf(56);
//        System.out.println(str);

//        float aa = (float) hex2decimal("6400");
//        System.out.println(aa);

//        float valtage = (float) hex2decimal("00231860");
//        System.out.println("电压" + valtage * 0.0001);

//        String ss = "0901000
//        System.out.println("FEFEFE68466854014300000001039020016316".length());
//        System.out.println("FEFEFE68465158064300000001039020015516".length());
    }


    public static String ceshi() {
//ceebic-BDC011-23081104-AA
        String ss = "48656c6c6f20576f726c64ig";
        // 转换为字符串
        String result = NettyUtils.bytes2hexFirst(stringToHex(ss));

        return result;
    }

    public static byte[] stringToHex(String string) {
        byte[] hexArray = new byte[string.length() / 2];
        for (int i = 0; i < string.length(); i += 2) {
            hexArray[i / 2] = (byte) ((Character.digit(string.charAt(i), 16) << 4)
                    + Character.digit(string.charAt(i + 1), 16));
        }
        return hexArray;
    }

    /**
     * 获取时间间隔的数据,隔interval个取一个
     *
     * @param list
     * @param interval
     * @param <T>
     * @return
     */
    public static <T> List getTIme(List<T> list, Integer interval) {
        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        if(list.size() < interval){
            return list;
        }

        List l = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if ((i + 1) == 1 || i % interval == 0) {
                l.add(list.get(i));
            }
        }
        return l;
    }

}